# coding:utf8
# 1.7字典中的键映射多个值
from collections import defaultdict

# d = defaultdict(list)
# d['a'].append(7)
# d['a'].append(1)
# d['b'].append(2)
# d['c'].append(5)
# print(d)
#
# d = defaultdict(set)
# d['a'].add(1)
# d['a'].add(2)
# d['b'].add(4)
# print(d)
# print(type(d))
#
# d = {}  # 一个普通的字典
# d.setdefault('a', [1])
# d.setdefault('a', []).append(2)
# d.setdefault('b', []).append(4)
# d.setdefault('c', 'a')
# print(d)

pairs = {
    "name": "Jack",
    "age": 18
}
d = {}
# for k, v in pairs:
#     print('a')
#     if k not in d:
#         d[k] = []
#     d[k].append(v)
# print(d)

"""
1.7字典排序
场景：用于对字典中的key-value需要排序的时候
知识点：collections中有OrderDict
"""
from collections import OrderedDict
import json

order_dict = OrderedDict()
order_dict['a'] = "a"
order_dict['b'] = "b"
order_dict['c'] = "c"
for key in order_dict:
    print(key, order_dict[key])
print(order_dict.move_to_end("a"))
print(json.dumps(order_dict))

"""
1.8字典的运算
适用于计算字典的value中的min,max
知识点：
zip():可以将键和值反转过来，且只能访问一次（迭代器）
sorted():可以将数字进行排序
min:取迭代器对象中的最小值
max:取最大值
lambda表达式：称之为匿名函数，与def函数不同之处：
  1.def函数有函数名称，而lambda没有
  2.lambda返回的是一个对象，而这个对象不会赋值给一个标识符，并不会返回具体的值
  3.lambda是一个表达式，而def是一个语句
  4.lambda表示式 ”:“后面，只能有一个表达式，def则可以有多个
  5.像if或for或print语句不能用于lambda中，def则可以
  6.lambda一般用来定义简单的函数，而def可以定义复杂的函数
"""
calculate_dict = {
    "aws": 9999,
    "apple": 12000,
    "tencent": 4500,
    "ali": 4600
}
zip_price = zip(calculate_dict.values(), calculate_dict.keys())
print("zip_price:{}".format(zip_price))
print(min(zip_price))
min_price = min(zip(calculate_dict.values(), calculate_dict.keys()))
print(min_price, type(min_price))
max_price = max(zip(calculate_dict.values(), calculate_dict.keys()))
print(max_price)
prices_sorted = sorted(zip(calculate_dict.values(), calculate_dict.keys()))
print(prices_sorted)
print(max(calculate_dict.values()))
print(min(calculate_dict.values()))
print(min(calculate_dict, key=lambda k: calculate_dict[k]))
print(calculate_dict[min(calculate_dict, key=lambda k: calculate_dict[k])])

"""
1.9查找两字典的相同点
场景：找到两个字典中相同的点
知识点：
1.字典就是键和值集合的映射，字典的keys()返回一个键视图对象，键视图支持集合操作，如集合的并，交，差运算生成一个set
2.items()返回的是一个包含键，值得元素视图对象。
3.字典的values()不支持集合操作，值不能保证所有的值互补相同，可以将值转换成set
"""
a = {
    "x": 1,
    "y": 2,
    "z": 3
}

b = {
    "w": 11,
    "x": 1,
    "y": 13,
}
print(a.keys() & b.keys())
print(a.items() & b.items())
print(a.keys() - b.keys())
print('values', set(a.values()) & set(b.values()))
print('values', set(a.values()) - set(b.values()))

c = {key: a[key] for key in a.keys() - {'z', 'w'}}
print(c)

"""
1.10 如何删除序列相同元素并保持顺序

"""


def queue(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)
    print(seen)


a = [1, 5, 2, 1, 9, 1, 5, 10]
print(list(queue(a)))


def dedupe(items, key=None):
    seen = set()
    for item in items:
        val = item if key is None else key(item)
        print("val", val, key)
        if val not in seen:
            yield item
            seen.add(val)
    print(seen)


a = [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
print(list(dedupe(a, key=lambda d: (d['x'], d['y']))))
